package com.woniuxy.sensitive.entity;

import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.springframework.core.io.ClassPathResource;

@Component
public class SensitiveWordInit {

    // 自己创建敏感词Map，而不是从外部注入
    private final Map<String, Object> sensitiveWordMap = new HashMap<>();

    // 基础敏感词库路径
    private static final String DEFAULT_SENSITIVE_WORDS_PATH = "sensitive_words.txt";

    @PostConstruct
    public void init() {
        try {
            // 加载基础敏感词库
            Set<String> wordSet = loadSensitiveWordsFromFile(DEFAULT_SENSITIVE_WORDS_PATH);
            // 构建DFA算法所需的敏感词库
            addSensitiveWordToHashMap(wordSet);
        } catch (IOException e) {
            throw new RuntimeException("初始化敏感词库失败", e);
        }
    }

    // 提供获取敏感词Map的方法，供Service使用
    public Map<String, Object> getSensitiveWordMap() {
        return sensitiveWordMap;
    }

    private Set<String> loadSensitiveWordsFromFile(String filePath) throws IOException {
        Set<String> wordSet = new HashSet<>();
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(new ClassPathResource(filePath).getInputStream(), StandardCharsets.UTF_8))) {
            String word;
            while ((word = br.readLine()) != null) {
                wordSet.add(word.trim());
            }
        }
        return wordSet;
    }

    @SuppressWarnings("unchecked")
    private void addSensitiveWordToHashMap(Set<String> wordSet) {
        sensitiveWordMap.clear(); // 清空现有数据
        Map<String, Object> nowMap;
        for (String word : wordSet) {
            nowMap = sensitiveWordMap;
            for (int i = 0; i < word.length(); i++) {
                char keyChar = word.charAt(i);
                String key = String.valueOf(keyChar); // 使用String作为键
                Object tempMap = nowMap.get(key);

                if (tempMap != null) {
                    nowMap = (Map<String, Object>) tempMap;
                } else {
                    Map<String, Object> newMap = new HashMap<>();
                    newMap.put("isEnd", "0");
                    nowMap.put(key, newMap);
                    nowMap = newMap;
                }

                if (i == word.length() - 1) {
                    nowMap.put("isEnd", "1");
                }
            }
        }
    }
}